let currentNetwork = "";
let currentNetworkURL = "";


// 按钮操作函数
async function createNetwork() {
  const name = await customPrompt("语义网络名称：");
  if (name) {
    // 用户输入了内容
    console.log("用户输入的名称:", name);
    let source = [{
      nodeName: "@语义网络组"
    },
    {
      nodeName: "语义网络名称",
      value: name
    }];
    const result = await manageTake(source, "创建");
    updateNetworkTree();
    handleNetworkSelection(name);
  } else {
    // 用户取消了输入
    console.log("用户取消了输入");
  }
}

async function copyNetwork() {
  if (!currentNetwork || currentNetwork.length == 0) {
    showToast("请选择语义网络", "warning");
    return;
  }
  let source = [{
    nodeName: "语义网络",
    value: currentNetwork
  }];
  const result = await manageTake(source, "复制");
  updateNetworkTree();
}


async function importNetwork() {
  createFormDialog([
    {
      name: 'name',
      label: '语义网络名称',
      type: 'text',
      required: true
    },
    {
      name: 'url',
      label: '语义网络实现URL',
      type: 'text',
      min: 10,
      max: 120,
      required: true
    }
  ], {
    title: '导入语义网络'
  }).then(result => {
    if (result) {
      let source = [{
        nodeName: "@语义网络组"
      },
      {
        nodeName: "语义网络名称",
        value: result.name
      }, {
        nodeName: "语义网络实现URL",
        value: result.url
      }];
      manageTake(source, "导入");
      updateNetworkTree();
    }
  });
}

async function mergeNetworks() {
  if (!currentNetwork || currentNetwork.length == 0) {
    showToast("请选择语义网络", "warning");
    return;
  }
  const name = await customPrompt("导入的语义网路链接：");
  let source = [{
    nodeName: "semanticImplement",
    value: "semanticImplement"
  }, {
    nodeName: "semanticImplementUrl",
    value: name
  }];
  const result = await conceptTake(source, "merge");
  loadNetworkData();
}

async function registerImplementer() {
  if (!currentNetwork || currentNetwork.length == 0) {
    showToast("请选择语义网络", "warning");
    return;
  }
  createFormDialog([
    {
      name: 'provierName',
      label: '实现器名称',
      type: 'text',
      min: 10,
      max: 120,
      required: true
    },
    {
      name: 'url',
      label: '实现器',
      type: 'text',
      required: true
    }
  ], {
    title: '注册语义网络实现器'
  }).then(result => {
    if (result) {
      let source = [{
        nodeName: "语义网络",
        value: currentNetwork
      },
      {
        nodeName: "实现器",
        value: result.url
      }, {
        nodeName: "实现器名称",
        value: result.provierName
      }];

      new Promise((resolve) => {
        manageTake(source, "注册实现器");
      }).then(result => {
        loadNetProvider();
      });

    }
  });
}

async function deleteNetwork() {
  if (!currentNetwork || currentNetwork.length == 0) {
    showToast("请选择语义网络", "warning");
    return;
  }
  const cDelete = confirmDelete(currentNetwork);
  if (!cDelete) {
    return;
  }
  let source = [{
    nodeName: "语义网络",
    value: currentNetwork
  }];
  const result = await manageTake(source, "删除");
  currentNetwork = "";
  currentNetworkURL = "";
  updateNetworkTree();
}

function confirmDelete(currentNetwork) {
  return confirm("确定删除语义网络：" + currentNetwork + "？");
}


// 代码提交处理
async function submitCode() {
  const code = document.getElementById('code-editor').value;
  let source = [{
    nodeName: "语义网络名称",
    value: currentNetwork
  }, {
    nodeName: "语义网络脚本",
    value: code
  }];
  const result = await manageTake(source, "执行");
  document.getElementById('code-editor').value = "";
  loadNetworkData();
}

// 执行命令处理
async function executeCommand() {
  const command = document.getElementById('command-input').value;
  let source = [];
  const parts = command.split(';');
  console.log(parts);
  let dest = parts[1];
  const sourceArray = parts[0].split(',');
  for (let i = 0; i < sourceArray.length; i++) {
    const node = sourceArray[i].split(':');
    if (node.length < 2) {
      source.push({ nodeName: node[0].trim() });
    } else {
      source.push({
        nodeName: node[0].trim(),
        value: node[1].trim()
      });
    }
  }

  try {
    const result = await taskPath(currentNetworkURL, source, dest);
    // 使用新的JSON格式化显示结果
    document.getElementById('results-area').innerHTML =
      `<pre>${toPrettyJson(result)}</pre>`;
  } catch (error) {
    document.getElementById('results-area').innerHTML =
      `<pre>${toPrettyJson({ error: error.message })}</pre>`;
  }
}

async function possiblePathQuery() {


  const command = document.getElementById('command-input').value;
  let source = [];
  const parts = command.split(';');
  console.log(parts);
  let dest = parts[1];
  const sourceArray = parts[0].split(',');
  for (let i = 0; i < sourceArray.length; i++) {
    const node = sourceArray[i].split(':');
    source.push(node[0].trim());
  }
  try {
    const result = await conceptTake([{
      nodeName: "source",
      value: source
    }, {
      nodeName: "dest",
      value: dest
    }], "possibleRelationChain");
    document.getElementById('results-area').innerHTML =
      `<pre>${toPrettyJson(result)}</pre>`;
  } catch (error) {
    document.getElementById('results-area').innerHTML =
      `<pre>${toPrettyJson({ error: error.message })}</pre>`;
  }


}

async function exactlyPathQuery() {

  const command = document.getElementById('command-input').value;
  let source = [];
  const parts = command.split(';');
  console.log(parts);
  let dest = parts[1];
  const sourceArray = parts[0].split(',');
  for (let i = 0; i < sourceArray.length; i++) {
    const node = sourceArray[i].split(':');
    source.push(node[0].trim());
  }
  try {
    const result = await conceptTake([{
      nodeName: "source",
      value: source
    }, {
      nodeName: "dest",
      value: dest
    }], "exactlyRelationChain");
    document.getElementById('results-area').innerHTML =
      `<pre>${toPrettyJson(result)}</pre>`;
  } catch (error) {
    document.getElementById('results-area').innerHTML =
      `<pre>${toPrettyJson({ error: error.message })}</pre>`;
  }

}


function toPrettyJson(obj) {
  return JSON.stringify(obj, null, 2);
}

async function taskPath(url, source, dest) {
  const response = await fetch(url,
    {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        from: source,
        destObject: dest
      })
    }
  ); // 替换为你的后端接口
  if (!response.ok) {
    throw new Error('Network response was not ok');
  }
  const data = await response.json();
  if (!data.success) {
    console.error('Error:', data.errorMessage);
    throw new Error(data.errorMessage);
  }
  return data.result;
}

async function manageTake(source, dest) {
  const url = '/manage/controller/semantic';
  try {
    const result = await taskPath(url, source, dest);
    return result;
  } catch (error) {
    showToast(error, "error");
    throw error;
  }
}

/**
 * Executes a concept take operation between source and destination nodes
 * @param {string} source - The source node identifier
 * @param {string} dest - The destination node identifier
 * @returns {Promise<Object>} Result of the task path operation
 * @throws {Error} Shows error toast if operation fails
 */
async function conceptTake(source, dest) {
  try {
    const result = await taskPath(currentNetworkURL, source, dest);
    return result;
  } catch (error) {
    showToast(error, "error");
  }
}


function customPrompt(title, defaultValue = "") {
  return new Promise((resolve) => {
    const modal = document.getElementById('customPromptModal');
    const input = document.getElementById('customPromptInput');
    const titleElement = document.getElementById('promptTitle');

    // 设置标题和默认值
    titleElement.textContent = title || "请输入";
    input.value = defaultValue;

    // 显示模态框
    modal.style.display = 'flex';
    input.focus();

    // 确认按钮点击事件
    document.getElementById('promptConfirmBtn').onclick = function () {
      modal.style.display = 'none';
      resolve(input.value);
    };

    // 取消按钮点击事件
    document.getElementById('promptCancelBtn').onclick = function () {
      modal.style.display = 'none';
      resolve(null);
    };

    // 按Enter键确认
    input.onkeydown = function (e) {
      if (e.key === 'Enter') {
        modal.style.display = 'none';
        resolve(input.value);
      }
    };

    // 点击模态框外部关闭
    modal.onclick = function (e) {
      if (e.target === modal) {
        modal.style.display = 'none';
        resolve(null);
      }
    };
  });
}

/**
 * 显示自动消失的提示消息
 * @param {string} message 要显示的消息内容
 * @param {string} type 消息类型：'success'|'warning'|'error'|'info' (默认: 'info')
 * @param {number} duration 显示持续时间(毫秒) (默认: 3000)
 */
function showToast(message, type = 'info', duration = 3000) {
  const toast = document.getElementById('toastNotification');
  const toastMessage = document.getElementById('toastMessage');

  // 设置消息内容和类型
  toastMessage.textContent = message;

  // 重置类名并添加当前类型
  toast.className = 'toast';
  toast.classList.add(type);

  // 显示提示
  toast.style.display = 'block';

  // 设置自动隐藏
  setTimeout(() => {
    toast.style.animation = 'fadeOut 0.5s ease-out';
    setTimeout(() => {
      toast.style.display = 'none';
      toast.style.animation = '';
    }, 500);
  }, duration);
}

let networkTree = null;

// 初始化网络树事件
async function initNetworkTree() {
  const demoData = [];

  let source = [{
    nodeName: "语义网络组",
    value: ""
  }];
  const groupLs = await manageTake(source, "语义网络名称");
  groupLs.forEach((item) => {
    demoData.push({
      name: item,
      expanded: true,
      children: []
    });
  });

  const container = document.getElementById('network-tree');

  if (networkTree) {
    networkTree.init(demoData);
  } else {
    networkTree = new Tree(container, demoData, {
      onNodeClick: (nodeInfo) => {
        console.log('节点被点击:', nodeInfo);
        handleNetworkSelection(nodeInfo);
      }
    });
  }

  if (groupLs && groupLs.length > 0 && currentNetwork == "") {
    handleNetworkSelection(groupLs[0]);
  }

}

// 处理网络选择
async function handleNetworkSelection(text) {

  // 业务逻辑
  console.log(`已选择网络: ${text}`);
  currentNetwork = text;
  let source = [{
    nodeName: "语义网络名称",
    value: currentNetwork
  }];
  const result = await manageTake(source, "语义网络实现URL");
  currentNetworkURL = result[0];
  document.getElementById('network-url').href = currentNetworkURL;
  document.getElementById('network-url').textContent = currentNetworkURL;
  loadNetworkData();
  showToast(`已加载网络: ${text}`, 'success');
}

let thingTree = null;
let defineTree = null;
let instanceTree = null;



function searchTree() {

  const searchBox = document.getElementById('search-box');
  const keyword = searchBox.value.trim();
  if (thingTree) {
    thingTree.search(keyword);
  }
  if (defineTree) {
    defineTree.search(keyword);
  }
  if (instanceTree) {
    instanceTree.search(keyword);
  }
}


async function loadNetworkData() {

  // 加载事物列表
  {
    let source = [{
      nodeName: "semanticNet",
      value: currentNetwork
    }];
    let nodeLs = await conceptTake(source, "node");

    if (!nodeLs) {
      nodeLs = [];
    }
    const demoData = [];

    nodeLs.forEach((item) => {
      demoData.push({
        name: item.name,
        expanded: true,
        children: []
      });
    });

    const container = document.getElementById('thing-tree');

    if (thingTree) {
      thingTree.init(demoData);
    } else {
      thingTree = new Tree(container, demoData);
    }
  }

  // 加载关系定义
  {
    let source = [{
      nodeName: "semanticNet",
      value: currentNetwork
    }];
    let nodeLs = await conceptTake(source, "relationDefine");

    if (!nodeLs) {
      nodeLs = [];
    }

    const demoData = [];

    nodeLs.forEach((item) => {
      let itemDefine = {
        name: item.name,
        expanded: false,
        children: []
      }
      item.relaItemDefs.forEach((relaItemDef) => {
        itemDefine.children.push({
          name: getRelationItemStr(relaItemDef),
          expanded: false,
          children: []
        });
      });
      demoData.push(itemDefine);
    });

    const container = document.getElementById('relation-define-tree');
    if (defineTree) {
      defineTree.init(demoData);
    } else {
      defineTree = new Tree(container, demoData);
    }
  }

  // 加载关系实例
  {
    let source = [{
      nodeName: "semanticNet",
      value: currentNetwork
    }];
    let nodeLs = await conceptTake(source, "relationInstance");

    if (!nodeLs) {
      nodeLs = [];
    }
    const demoData = [];

    const grouped = nodeLs.reduce((acc, item) => {
      const key = item.name;
      if (!acc[key]) {
        acc[key] = [];
      }
      acc[key].push(item);
      return acc;
    }, {});


    Object.entries(grouped).forEach((value, key) => {

      let itemDefine = {
        name: value[0],
        expanded: false,
        children: []
      }

      let allItem = [];

      value[1].forEach((relaItemDef) => {
        relaItemDef.relationItems.forEach(item => {
          allItem.push(item);
        });
      });

      allItem.forEach((relaItemDef) => {
        itemDefine.children.push({
          name: getRelationItemStr(relaItemDef),
          expanded: false,
          children: []
        });
      });

      demoData.push(itemDefine);
    });

    const container = document.getElementById('relation-instance-tree');
    if (instanceTree) {
      instanceTree.init(demoData);
    } else {
      instanceTree = new Tree(container, demoData, {
        onNodeDoubleClick: nodeId => {
          console.log('双击节点:', nodeId);
          let query = "";
          const parts = nodeId.split("->");
          if (parts.length != 2) {
            return;
          }
          let source = parts[0].split(",");
          query = source.map(node => { return truncateAfterBracket(node) }).join(":,")
          query += ":;" + truncateAfterBracket(parts[1]);
          document.getElementById('command-input').value = query;
        }
      });
    }
  }
  loadNetProvider();
  refreshRenderGraph();
}



function truncateAfterBracket(str) {
  // 找到第一个 ) 或 ] 的位置
  const bracketIndex = Math.min(
    str.indexOf(')') !== -1 ? str.indexOf(')') : Infinity,
    str.indexOf(']') !== -1 ? str.indexOf(']') : Infinity
  );

  // 如果没有找到 ) 或 ]，返回原字符串
  if (bracketIndex === Infinity) {
    return str.trim();
  }

  // 截取 ) 或 ] 之后的内容并去除首尾空格
  return str.slice(bracketIndex + 1).trim();
}



function getRelationItemStr(item) {

  return item.sourceObjectList.map((rangeObj) => {
    return getRangeObjStr(rangeObj);
  }).join(',')
    + "->"
    + getRangeObjStr(item.destObject);

}

function getRangeObjStr(rangeObj) {
  return getRangeStr(rangeObj.range) + rangeObj.objectName;
}

function getRangeStr(rangeObj) {
  if (rangeObj.start == 1 && rangeObj.end == 1) {
    return "";
  }
  let res = "";
  if (rangeObj.includeStart) {
    res += "[";
  } else {
    res += "(";
  }
  res += rangeObj.start + ",";
  if (rangeObj.end) {
    res += end;
  }
  if (rangeObj.includeEnd) {
    res += "]";
  } else {
    res += ")";
  }
  return res;

}


// 页面加载时初始化
window.addEventListener('DOMContentLoaded', initNetworkTree);


async function updateNetworkTree() {
  await initNetworkTree();
}


/**
 * 创建模态表单对话框
 * @param {Object|Array} fields 表单字段配置
 * @param {Object} [options] 可选参数
 * @returns {Promise} 返回用户输入的值
 */
function createFormDialog(fields, options = {}) {
  return new Promise((resolve) => {
    // 标准化字段配置
    const fieldConfigs = Array.isArray(fields) ? fields : [fields];

    // 创建模态框容器
    const modal = document.createElement('div');
    modal.className = 'modal-overlay';
    modal.style.cssText = `
      position: fixed;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      background-color: rgba(0, 0, 0, 0.5);
      display: flex;
      justify-content: center;
      align-items: center;
      z-index: 1000;
      opacity: 0;
      transition: opacity 0.3s ease;
    `;

    // 创建对话框内容
    const dialog = document.createElement('div');
    dialog.className = 'modal-dialog';
    dialog.style.cssText = `
      background: white;
      border-radius: 8px;
      width: min(90%, 500px);
      max-height: 90vh;
      overflow-y: auto;
      box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
      transform: translateY(-20px);
      transition: transform 0.3s ease;
    `;

    dialog.innerHTML = `
      <div class="modal-header">
        <h3>${options.title || '请输入信息'}</h3>
        <button class="modal-close">&times;</button>
      </div>
      <div class="modal-body">
        ${fieldConfigs.map(field => `
          <div class="form-group">
            <label for="${field.id || field.name}">${field.label}</label>
            ${createFieldHtml(field)}
          </div>
        `).join('')}
      </div>
      <div class="modal-footer">
        <button class="btn btn-cancel">取消</button>
        <button class="btn btn-submit">确认</button>
      </div>
    `;


    modal.appendChild(dialog);
    document.body.appendChild(modal);

    if (options.asMenu) {
      dialog.style.width = 'auto';
      dialog.style.minWidth = '150px';
      dialog.querySelector('.modal-body').style.padding = '0';

      fields.forEach(field => {
        if (field.type === 'button') {
          const btn = dialog.querySelector(`#${field.id || field.name}`);
          btn.style.width = '100%';
          btn.style.textAlign = 'left';
          btn.style.borderRadius = '0';
          btn.style.border = 'none';
          btn.style.padding = '8px 16px';
          btn.style.background = 'none';
          btn.addEventListener('click', () => {
            field.onClick();
            modal.remove();
            resolve();
          });
        }
      });
    }

    // 强制重绘，触发动画
    setTimeout(() => {
      modal.style.opacity = '1';
      dialog.style.transform = 'translateY(0)';
    }, 10);

    // 处理表单提交
    const submit = () => {
      const result = {};
      let isValid = true;

      fieldConfigs.forEach(field => {
        const input = dialog.querySelector(`#${field.id || field.name}`);
        if (field.required && !input.value) {
          input.style.borderColor = 'red';
          isValid = false;
        } else {
          result[field.name] = getInputValue(input, field.type);
        }
      });

      if (isValid) {
        modal.style.opacity = '0';
        dialog.style.transform = 'translateY(-20px)';
        setTimeout(() => {
          modal.remove();
          resolve(result);
        }, 300);
      }
    };

    // 处理取消/关闭
    const cancel = () => {
      modal.style.opacity = '0';
      dialog.style.transform = 'translateY(-20px)';
      setTimeout(() => {
        modal.remove();
        resolve(null);
      }, 300);
    };

    // 事件监听
    dialog.querySelector('.btn-submit').addEventListener('click', submit);
    dialog.querySelector('.btn-cancel').addEventListener('click', cancel);
    dialog.querySelector('.modal-close').addEventListener('click', cancel);

    // 点击外部关闭
    modal.addEventListener('click', (e) => {
      if (e.target === modal) cancel();
    });

    // 回车键提交
    dialog.addEventListener('keypress', (e) => {
      if (e.key === 'Enter') submit();
    });
  });
}

// 根据字段类型创建对应的HTML元素
function createFieldHtml(field) {
  const commonAttrs = `id="${field.id || field.name}" name="${field.name}" 
    placeholder="${field.placeholder || ''}" ${field.required ? 'required' : ''}`;
  switch (field.type || 'text') {
    case 'select':
      return `
        <select ${commonAttrs}>
          ${field.options.map(opt =>
        `<option value="${opt.value}" ${opt.selected ? 'selected' : ''}>
              ${opt.label || opt.value}
            </option>`
      ).join('')}
        </select>
      `;
    case 'textarea':
      return `<textarea ${commonAttrs} rows="${field.rows || 3}">${field.value || ''}</textarea>`;
    case 'checkbox':
      return `<input type="checkbox" ${commonAttrs} ${field.checked ? 'checked' : ''}>`;
    case 'radio':
      return field.options.map(opt => `
        <label>
          <input type="radio" name="${field.name}" value="${opt.value}" 
            ${opt.checked ? 'checked' : ''}>
          ${opt.label || opt.value}
        </label>
      `).join('');
    default:
      return `<input type="${field.type || 'text'}" ${commonAttrs} value="${field.value || ''}">`;
  }
}

// 获取输入值（根据类型处理）
function getInputValue(input, type) {
  if (!input) return null;

  switch (type) {
    case 'checkbox':
      return input.checked;
    case 'radio':
      return document.querySelector(`input[name="${input.name}"]:checked`)?.value;
    case 'number':
      return Number(input.value);
    default:
      return input.value;
  }
}

class Tree {
  constructor(container, data, options = {}) {
    this.container = container;
    this.data = data;
    this.originalData = JSON.parse(JSON.stringify(data)); // 保存原始数据
    this.onNodeClick = options.onNodeClick || (() => { });
    this.onNodeDoubleClick = options.onNodeDoubleClick || (() => { }); // 新增双击回调
    this.init(this.data);
    this.bindEvents();
  }

  init(data) {
    this.container.innerHTML = this.buildTree(data);
  }

  buildTree(nodes, level = 0) {
    return `
          <ul class="tree-node">
              ${nodes.map(node => `
                  <li>
                      <div class="tree-node__item" data-node-id="${node.name}" >
                          <div class="tree-node__content">
                              ${node.children ? `
                                  <span class="tree-node__arrow">
                                      <i class="fas fa-chevron-down"></i>
                                  </span>
                              ` : '<span style="width: 20px;"></span>'}
                              <i class="fas ${node.icon || 'fa-folder'} tree-node__icon"></i>
                              <span class="tree-node__label">${node.name}</span>
                          </div>
                      </div>
                      ${node.children ? `
                          <div class="tree-node__children ${!node.expanded ? 'collapsed' : ''}">
                              ${this.buildTree(node.children, level + 1)}
                          </div>
                      ` : ''}
                  </li>
              `).join('')}
          </ul>
      `;
  }

  bindEvents() {
    // 确保只绑定一次
    this.container.addEventListener('click', this.handleClick.bind(this));
    this.container.addEventListener('dblclick', this.handleDoubleClick.bind(this)); // 新增双击监听
  }
  /**
   * Handles click events on tree nodes
   * @param {Event} e - The click event object
   * @description Manages two types of clicks:
   * 1. Arrow clicks: Toggles expand/collapse state of tree node children
   * 2. Item clicks: Handles node selection and triggers onNodeClick callback
   * @private
   */
  handleClick(e) {
    // 如果是双击的第二次点击，忽略
    if (this.isDoubleClick) {
      this.isDoubleClick = false;
      return;
    }

    // 设置单击延迟检测
    clearTimeout(this.clickTimer);
    this.clickTimer = setTimeout(() => {
      const arrow = e.target.closest('.tree-node__arrow');
      const item = e.target.closest('.tree-node__item');

      if (arrow) {
        const children = arrow.closest('li').querySelector('.tree-node__children');
        if (children) {
          arrow.classList.toggle('collapsed');
          children.classList.toggle('collapsed');
        }
      }

      if (item) {
        document.querySelectorAll('.tree-node__item').forEach(el => {
          el.classList.remove('tree-node__item--selected');
        });
        item.classList.add('tree-node__item--selected');
        const nodeId = item.getAttribute('data-node-id');
        this.onNodeClick(nodeId);
      }
    }, 200); // 200ms延迟区分单击和双击
  }


  /**
 * 处理节点双击事件
 * @param {Event} e - 双击事件对象
 */
  handleDoubleClick(e) {
    const item = e.target.closest('.tree-node__item');
    if (!item) return;

    // 阻止双击触发两次单击事件
    e.preventDefault();
    e.stopPropagation();

    const nodeId = item.getAttribute('data-node-id');
    this.onNodeDoubleClick(nodeId);
  }

  /**
   * 搜索树节点并高亮显示匹配项
   * @param {string} keyword - 搜索关键词
   */
  search(keyword) {
    if (!keyword.trim()) {
      // 如果关键词为空，恢复原始数据
      this.init(this.originalData);
      return;
    }

    const filteredData = this.filterTree(this.originalData, keyword.toLowerCase());
    this.init(filteredData);
    this.highlightMatches(keyword);
  }

  /**
   * 递归过滤树数据
   */
  filterTree(nodes, keyword) {
    return nodes
      .map(node => ({ ...node })) // 浅拷贝节点
      .filter(node => {
        // 检查当前节点是否匹配
        const isMatch = node.name.toLowerCase().includes(keyword);

        // 如果有子节点，递归过滤
        if (node.children) {
          node.children = this.filterTree(node.children, keyword);
          // 如果子节点有匹配，当前节点也应该保留
          return isMatch || node.children.length > 0;
        }

        return isMatch;
      });
  }

  /**
   * 高亮匹配的文本
   */
  highlightMatches(keyword) {
    const labels = this.container.querySelectorAll('.tree-node__label');
    const regex = new RegExp(keyword, 'gi');

    labels.forEach(label => {
      const text = label.textContent;
      if (regex.test(text)) {
        label.innerHTML = text.replace(
          regex,
          match => `<span class="tree-node__highlight">${match}</span>`
        );
      }
    });
  }
}


document.getElementById('copy-url-btn').addEventListener('click', function () {
  const urlElement = document.getElementById('network-url');
  const url = urlElement.href || urlElement.textContent;

  navigator.clipboard.writeText(url).then(() => {
    // 显示复制成功反馈
    const originalText = this.innerHTML;
    this.innerHTML = '<i class="copy-icon">✓</i>';

    // 2秒后恢复原状
    setTimeout(() => {
      this.innerHTML = originalText;
    }, 2000);
  }).catch(err => {
    console.error('复制失败:', err);
    alert('复制失败，请手动选择地址复制');
  });
});


// 选项配置API
const optionsManager = {
  // 初始化选项容器
  container: document.getElementById('dynamic-options-container'),

  // 设置选项列表
  setOptions: function (options) {
    this.container.innerHTML = '';
    options.forEach(option => {
      const optionEl = document.createElement('div');
      optionEl.className = 'option-item';

      const checkbox = document.createElement('input');
      checkbox.type = 'checkbox';
      checkbox.id = `option-${option.id}`;
      checkbox.checked = option.checked || false;

      const label = document.createElement('label');
      label.htmlFor = `option-${option.id}`;
      label.textContent = option.label;

      optionEl.appendChild(checkbox);
      optionEl.appendChild(label);
      this.container.appendChild(optionEl);
    });
  },

  // 获取当前选中项
  getSelectedOptions: function () {
    const checkboxes = this.container.querySelectorAll('input[type="checkbox"]');
    return Array.from(checkboxes)
      .filter(cb => cb.checked)
      .map(cb => cb.id.replace('option-', ''));
  },

  // 更新单个选项状态
  updateOption: function (id, checked) {
    const checkbox = document.getElementById(`option-${id}`);
    if (checkbox) {
      checkbox.checked = checked;
    }
  }
};


async function loadNetProvider() {

  let source = [{
    nodeName: "semanticImplement",
    value: ""
  }];
  const groupLs = await conceptTake(source, "functionProvider");

  // 使用示例：
  // 1. 初始化选项列表
  const sampleOptions = [
  ];
  groupLs.forEach((item) => {
    sampleOptions.push({ id: item, label: item, checked: true });
  });
  optionsManager.setOptions(sampleOptions);

}

// 2. 获取当前选中项（可以在执行命令时使用）
function executeOptionCommand() {
  const selectedOptions = optionsManager.getSelectedOptions();
  console.log("当前选中的选项:", selectedOptions);
  // 您的执行逻辑...
}

// 3. 动态更新选项（可以从其他代码调用）
function toggleOption(optionId, checked) {
  optionsManager.updateOption(optionId, checked);
}


// 渲染图形（支持缩放、自定义颜色和名称转换）
function renderGraph(nodesData, linksData) {
  const graphEditor = d3.select('#graph-editor');
  graphEditor.selectAll('*').remove(); // 清空容器

  if (!nodesData || !nodesData.length) {
    graphEditor.append('p').text('没有可显示的节点数据');
    return;
  }

  const width = graphEditor.node().clientWidth;
  const height = graphEditor.node().clientHeight;

  // 创建SVG画布和缩放容器
  const svg = graphEditor.append('svg')
    .attr('width', width)
    .attr('height', height)
    .call(d3.zoom()
      .scaleExtent([graphConfig.zoom.min, graphConfig.zoom.max])
      .on('zoom', (event) => {
        g.attr('transform', event.transform);
      }))
    .on('dblclick.zoom', null); // 禁用默认的双击缩放

  // 主图形组
  const g = svg.append('g');

  // 添加箭头标记
  g.append('defs').selectAll('marker')
    .data(['end'])
    .enter().append('marker')
    .attr('id', d => d)
    .attr('viewBox', '0 -5 10 10')
    .attr('refX', 25)
    .attr('refY', 0)
    .attr('markerWidth', 6)
    .attr('markerHeight', 6)
    .attr('orient', 'auto')
    .append('path')
    .attr('d', 'M0,-5L10,0L0,5')
    .attr('fill', graphConfig.linkColors.default);

  // 处理数据
  const nodes = nodesData.map(node => ({
    id: node.id,
    displayName: node.name,
    x: node.x || Math.random() * width,
    y: node.y || Math.random() * height
  }));

  const links = linksData.map(link => ({
    source: nodes.find(n => n.id === link.from),
    target: nodes.find(n => n.id === link.to)
  }));

  // 创建力导向图模拟
  const simulation = d3.forceSimulation(nodes)
    .force('link', d3.forceLink(links).id(d => d.id).distance(100))
    .force('charge', d3.forceManyBody().strength(-300))
    .force('center', d3.forceCenter(width / 2, height / 2));

  // 绘制连线
  const link = g.append('g')
    .selectAll('line')
    .data(links)
    .enter().append('line')
    .attr('class', 'link')
    .attr('stroke', graphConfig.linkColors.default)
    .attr('stroke-width', 2)
    .attr('marker-end', 'url(#end)')
    .on('mouseover', function () {
      d3.select(this)
        .attr('stroke', graphConfig.linkColors.highlight)
        .attr('stroke-width', 4);
    })
    .on('mouseout', function () {
      d3.select(this)
        .attr('stroke', graphConfig.linkColors.default)
        .attr('stroke-width', 2);
    })
    .on('contextmenu', function (event, d) {
      event.preventDefault();
      showLinkContextMenu(event, d);
    });

  // 绘制节点
  const node = g.append('g')
    .selectAll('g')
    .data(nodes)
    .enter().append('g')
    .call(d3.drag()
      .on('start', dragstarted)
      .on('drag', dragged)
      .on('end', dragended))
    .on('mouseover', function () {
      d3.select(this).select('circle')
        .attr('fill', graphConfig.nodeColors.highlight)
        .attr('r', 14);
    })
    .on('mouseout', function () {
      d3.select(this).select('circle')
        .attr('fill', graphConfig.nodeColors.default)
        .attr('r', 12);
    })
    .on('contextmenu', function (event, d) {
      event.preventDefault();
      showNodeContextMenu(event, d);
    });

  // 添加节点圆形
  node.append('circle')
    .attr('class', 'node')
    .attr('r', 12)
    .attr('fill', graphConfig.nodeColors.default)
    .attr('stroke', '#fff')
    .attr('stroke-width', 2);

  // 添加节点文本
  node.append('text')
    .attr('class', 'node-text')
    .attr('dy', 4)
    .attr('text-anchor', 'middle')
    .attr('fill', graphConfig.nodeColors.text)
    .text(d => d.displayName);

  // 更新力导向图
  simulation.on('tick', () => {
    link
      .attr('x1', d => d.source.x)
      .attr('y1', d => d.source.y)
      .attr('x2', d => d.target.x)
      .attr('y2', d => d.target.y);

    node.attr('transform', d => `translate(${d.x},${d.y})`);
  });

  // 双击重置缩放
  svg.on('dblclick', () => {
    svg.transition()
      .duration(750)
      .call(d3.zoom().transform, d3.zoomIdentity);
  });

  // 拖拽函数
  function dragstarted(event, d) {
    if (!event.active) simulation.alphaTarget(0.3).restart();
    d.fx = d.x;
    d.fy = d.y;
  }

  function dragged(event, d) {
    d.fx = event.x;
    d.fy = event.y;
  }

  function dragended(event, d) {
    if (!event.active) simulation.alphaTarget(0);
    d.fx = null;
    d.fy = null;
  }

  // 显示边右键菜单
  function showLinkContextMenu(event, linkData) {
    const menuItems = [
      { label: '移除边', action: () => { } },
      { label: '同值映射', action: () => { } }
    ];
    showContextMenu(event, menuItems, '边操作');
  }

  // 显示节点右键菜单
  function showNodeContextMenu(event, nodeData) {
    const menuItems = [
      { label: '移除节点', action: () => { } },
      { label: '隐藏节点', action: () => { } },
      { label: '编辑属性', action: () => { } }
    ];
    showContextMenu(event, menuItems, '节点操作');
  }

  // 显示上下文菜单
  function showContextMenu(event, items, title) {
    const contextMenu = d3.select('#graph-editor')
      .append('div')
      .attr('class', 'context-menu')
      .style('position', 'absolute')
      .style('left', `${event.clientX}px`)
      .style('top', `${event.clientY}px`)
      .style('background', 'white')
      .style('border', '1px solid #ddd')
      .style('border-radius', '4px')
      .style('box-shadow', '0 2px 10px rgba(0,0,0,0.2)')
      .style('z-index', '1000');

    // 添加标题
    contextMenu.append('div')
      .attr('class', 'menu-header')
      .style('padding', '8px 12px')
      .style('border-bottom', '1px solid #eee')
      .style('font-weight', 'bold')
      .text(title);

    // 添加菜单项
    items.forEach(item => {
      contextMenu.append('div')
        .attr('class', 'menu-item')
        .style('padding', '8px 12px')
        .style('cursor', 'pointer')
        .style('border-bottom', '1px solid #eee')
        .on('mouseover', function () {
          d3.select(this).style('background', '#f5f5f5');
        })
        .on('mouseout', function () {
          d3.select(this).style('background', 'white');
        })
        .on('click', () => {
          item.action();
          contextMenu.remove();
        })
        .text(item.label);
    });

    // 点击其他地方关闭菜单
    d3.select('body').on('click.contextmenu', () => {
      contextMenu.remove();
      d3.select('body').on('click.contextmenu', null);
    }, true);
  }
}

// 图形配置
// 增强版图形配置
const graphConfig = {
  nodeColors: {
    default: '#ffffff',      // 白色填充（与CSS一致）
    border: '#2ca02c',      // 绿色边框
    highlight: '#ff7f0e',    // 悬停时橙色边框
    text: '#000000',        // 黑色文本
    textHighlight: '#333333'// 悬停时文本颜色
  },
  linkColors: {
    default: '#2ca02c',     // 绿色连线
    highlight: '#ff7f0e',   // 悬停时橙色连线
    opacity: 0.8            // 连线透明度
  },
  dimensions: {
    nodeRadius: 12,         // 默认节点半径
    nodeHoverRadius: 14,    // 悬停时半径
    borderWidth: 2,         // 边框宽度
    linkWidth: 2,           // 连线宽度
    linkHoverWidth: 4       // 悬停连线宽度
  },
  zoom: {
    min: 0.1,
    max: 8,
    duration: 750           // 缩放动画时长(ms)
  },
  transitions: {
    duration: 300           // 悬停动画时长(ms)
  }
};



// 节点名称转换函数 - 现在直接从节点数据获取name
function transformNodeName(nodeId, nodesData) {
  const node = nodesData.find(n => n.id === nodeId);
  return node ? node.name : nodeId;
}

// 渲染图形（支持缩放、自定义颜色和名称转换）
function renderGraph(nodesData, linksData) {
  const graphEditor = d3.select('#graph-editor');
  graphEditor.selectAll('*').remove(); // 清空容器

  if (!nodesData || !nodesData.length) {
    graphEditor.append('p').text('没有可显示的节点数据');
    return;
  }

  const width = graphEditor.node().clientWidth;
  const height = graphEditor.node().clientHeight;

  // 创建SVG画布和缩放容器
  const svg = graphEditor.append('svg')
    .attr('width', width)
    .attr('height', height)
    .call(d3.zoom()
      .scaleExtent([graphConfig.zoom.min, graphConfig.zoom.max])
      .on('zoom', (event) => {
        g.attr('transform', event.transform);
      }))
    .on('dblclick.zoom', null); // 禁用默认的双击缩放

  // 主图形组
  const g = svg.append('g');

  // 添加箭头标记
  // 修改defs部分，定义两种箭头（正向和反向）
  g.append('defs').selectAll('marker')
    .data([
      { id: 'end', color: graphConfig.linkColors.default },
      { id: 'start', color: graphConfig.linkColors.default },
      { id: 'end-highlight', color: graphConfig.linkColors.highlight },
      { id: 'start-highlight', color: graphConfig.linkColors.highlight }
    ])
    .enter().append('marker')
    .attr('id', d => d.id)
    .attr('viewBox', '0 -5 10 10')
    .attr('refX', d => d.id.includes('start') ? -5 : 25)
    .attr('refY', 0)
    .attr('markerWidth', 6)
    .attr('markerHeight', 6)
    .attr('orient', 'auto')
    .append('path')
    .attr('d', 'M0,-5L10,0L0,5')
    .attr('fill', d => d.color);

  // 处理数据
  const nodes = nodesData.map(node => ({
    id: node.id,
    displayName: node.name,
    x: node.x || Math.random() * width,
    y: node.y || Math.random() * height
  }));

  const links = linksData.map(link => ({
    source: nodes.find(n => n.id === link.from),
    target: nodes.find(n => n.id === link.to)
  }));

  // 创建力导向图模拟
  const simulation = d3.forceSimulation(nodes)
    .force('link', d3.forceLink(links)
      .id(d => d.id)
      .distance(200) // 增加连线距离
      .iterations(2) // 提高计算精度
    )
    .force('charge', d3.forceManyBody().strength(-300))
    .force('center', d3.forceCenter(width / 2, height / 2));

  // 绘制连线
  // 绘制连线时添加双向箭头
  const link = g.append('g')
    .selectAll('line')
    .data(links)
    .enter().append('line')
    .attr('class', 'link')
    .attr('stroke', graphConfig.linkColors.default)
    .attr('stroke-width', 2)
    .attr('marker-end', 'url(#end)')
    .attr('marker-start', 'url(#start)')
    .on('mouseover', function (event, d) {
      // 计算鼠标到连线的距离
      const mouse = d3.pointer(event, this);
      const line = {
        x1: +d3.select(this).attr('x1'),
        y1: +d3.select(this).attr('y1'),
        x2: +d3.select(this).attr('x2'),
        y2: +d3.select(this).attr('y2')
      };

      // 计算距离起点和终点的距离
      const distToStart = Math.sqrt(Math.pow(mouse[0] - line.x1, 2) + Math.pow(mouse[1] - line.y1, 2));
      const distToEnd = Math.sqrt(Math.pow(mouse[0] - line.x2, 2) + Math.pow(mouse[1] - line.y2, 2));

      // 根据距离决定高亮哪个箭头
      if (distToStart < distToEnd) {
        d3.select(this)
          .attr('stroke', graphConfig.linkColors.highlight)
          .attr('marker-start', 'url(#start-highlight)')
          .attr('marker-end', null);
      } else {
        d3.select(this)
          .attr('stroke', graphConfig.linkColors.highlight)
          .attr('marker-end', 'url(#end-highlight)')
          .attr('marker-start', null);
      }
    })
    .on('mouseout', function () {
      d3.select(this)
        .attr('stroke', graphConfig.linkColors.default)
        .attr('marker-end', 'url(#end)')
        .attr('marker-start', 'url(#start)');
    })
    .on('contextmenu', function (event, d) {
      event.preventDefault();
      // 确定当前高亮的是哪个方向的连线
      const isStartHighlighted = d3.select(this).attr('marker-start') === 'url(#start-highlight)';
      showLinkContextMenu(event, {
        ...d,
        direction: isStartHighlighted ? 'reverse' : 'forward'
      });
    });
  // 绘制节点部分修改如下：

  // 绘制节点组
  const node = g.append('g')
    .selectAll('g')
    .data(nodes)
    .enter().append('g')
    .call(d3.drag()
      .on('start', dragstarted)
      .on('drag', dragged)
      .on('end', dragended))
    .on('mouseover', function () {
      d3.select(this).select('circle')
        .attr('stroke', graphConfig.nodeColors.highlight) // 悬停时橙色边框
        .attr('r', 14);
    })
    .on('mouseout', function () {
      d3.select(this).select('circle')
        .attr('stroke', graphConfig.nodeColors.border) // 恢复绿色边框
        .attr('r', 12);
    });

  // 添加节点圆形（关键修改部分）
  node.append('circle')
    .attr('class', 'node') // 保留CSS类
    .attr('r', 12)
    .attr('fill', graphConfig.nodeColors.default) // 白色填充
    .attr('stroke', graphConfig.nodeColors.border) // 绿色边框
    .attr('stroke-width', 2)
    .on('contextmenu', function(event, d) {
      event.preventDefault();
      showNodeContextMenu(event, d);
    });

  // 节点文本保持不变
  node.append('text')
    .attr('class', 'node-text')
    .attr('dy', 4)
    .text(d => d.displayName);


  // 更新力导向图
  simulation.on('tick', () => {
    link
      .attr('x1', d => d.source.x)
      .attr('y1', d => d.source.y)
      .attr('x2', d => d.target.x)
      .attr('y2', d => d.target.y);

    node.attr('transform', d => `translate(${d.x},${d.y})`);
  });

  // 双击重置缩放
  svg.on('dblclick', () => {
    svg.transition()
      .duration(750)
      .call(d3.zoom().transform, d3.zoomIdentity);
  });

  // 拖拽函数
  function dragstarted(event, d) {
    if (!event.active) simulation.alphaTarget(0.3).restart();
    d.fx = d.x;
    d.fy = d.y;
  }

  function dragged(event, d) {
    d.fx = event.x;
    d.fy = event.y;
  }

  function dragended(event, d) {
    if (!event.active) simulation.alphaTarget(0);
    d.fx = null;
    d.fy = null;
  }

  // 显示边右键菜单
  function showLinkContextMenu(event, linkData) {
    const menuItems = [
      { label: '移除边', action: () => { } },
      { label: '同值映射', action: () => { } }
    ];
    showContextMenu(event, menuItems, '边操作');
  }

  // 显示节点右键菜单
  function showNodeContextMenu(event, nodeData) {
    const menuItems = [
      { label: '移除节点', action: () => { } },
      { label: '隐藏节点', action: () => { } },
      { label: '编辑属性', action: () => { } }
    ];
    showContextMenu(event, menuItems, '节点操作');
  }

  // 显示上下文菜单
  function showContextMenu(event, items, title) {
    const contextMenu = d3.select('#graph-editor')
      .append('div')
      .attr('class', 'context-menu')
      .style('position', 'absolute')
      .style('left', `${event.clientX}px`)
      .style('top', `${event.clientY}px`)
      .style('background', 'white')
      .style('border', '1px solid #ddd')
      .style('border-radius', '4px')
      .style('box-shadow', '0 2px 10px rgba(0,0,0,0.2)')
      .style('z-index', '1000');

    // 添加标题
    contextMenu.append('div')
      .attr('class', 'menu-header')
      .style('padding', '8px 12px')
      .style('border-bottom', '1px solid #eee')
      .style('font-weight', 'bold')
      .text(title);

    // 添加菜单项
    items.forEach(item => {
      contextMenu.append('div')
        .attr('class', 'menu-item')
        .style('padding', '8px 12px')
        .style('cursor', 'pointer')
        .style('border-bottom', '1px solid #eee')
        .on('mouseover', function () {
          d3.select(this).style('background', '#f5f5f5');
        })
        .on('mouseout', function () {
          d3.select(this).style('background', 'white');
        })
        .on('click', () => {
          item.action();
          contextMenu.remove();
        })
        .text(item.label);
    });

    // 点击其他地方关闭菜单
    d3.select('body').on('click.contextmenu', () => {
      contextMenu.remove();
      d3.select('body').on('click.contextmenu', null);
    }, true);
  }
}

// 视图切换函数
async function toggleViewMode() {
  const scriptView = document.getElementById('script-view');
  const graphView = document.getElementById('graph-view');
  const toggleBtn = document.getElementById('toggle-view-btn');

  //仅仅脚本可见
  if (scriptView.style.display !== 'none' && graphView.style.display === 'none') {
    // 切换到图形视图
    scriptView.style.display = 'none';
    graphView.style.display = 'block';
    refreshRenderGraph();
  } else if (scriptView.style.display === 'none' && graphView.style.display !== 'none') {
    // 都可以见的视图
    scriptView.style.display = 'block';
    graphView.style.display = 'block';
  }
  else {
    // 切换到脚本视图
    scriptView.style.display = 'block';
    graphView.style.display = 'none';
  }
}


async function refreshRenderGraph() {
  try {
    let source = [{
      nodeName: "semanticNet",
      value: currentNetwork
    }];
    const linkData = await conceptTake(source, "link");
    let source2 = [{
      nodeName: "semanticNet",
      value: currentNetwork
    }];
    const nodeData = await conceptTake(source2, "node");
    renderGraph(nodeData, linkData);
  } catch (e) {
    console.error('解析JSON数据失败:', e);
    renderGraph([]);
  }
}


// 初始化页面
document.addEventListener('DOMContentLoaded', async () => {
  // 添加视图切换按钮事件
  document.getElementById('toggle-view-btn').addEventListener('click', toggleViewMode);
  refreshRenderGraph();
});


function handleKeyDown(event) {
  // 检查是否按下了 Command/Ctrl + Enter
  if ((event.metaKey || event.ctrlKey) && event.keyCode === 13) {
    submitCode();
    // 阻止默认行为
    event.preventDefault();
  }
}

async function saveNetwork() {
  if (!currentNetwork || currentNetwork.length == 0) {
    showToast("请选择语义网络", "warning");
    return;
  }
  let source = [{
    nodeName: "语义网络",
    value: currentNetwork
  }];
  try {
    const result = await manageTake(source, "保存");
    showToast("保存成功", "success");
  } catch (error) {
    showToast("保存失败: " + error, "error");
  }
}